"""
Case Type   : A兼容性-type功能增强
Case Name   : 使用type创建member/static方法，并调用
Create At   : 2025/5/22
Owner       : wan005
Description :
    1.创建类型定义构造函数/menber/static方法
    2.创建类型体
    3.调用类型体member、static方法
Expect      :
    1.成功
    2.成功
    3.成功
History     :
"""
import os
import unittest
from yat.test import Node
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Logger import Logger


class Security(unittest.TestCase):
    def setUp(self):
        self.logger = Logger()
        self.logger.info(f'---{os.path.basename(__file__)} start---')
        self.userNode = Node(node='PrimaryDbAmode')
        self.sh_primy = CommonSH()
        self.common = Common()
        self.db_name = self.userNode.db_name
        self.type = 't_051'

    def test_security(self):
        text = '----pre:加载A库gms插件;expect:成功----'
        self.logger.info(text)
        load_cmd = "create extension if not exists gms_output;"
        load_res = self.sh_primy.execut_db_sql(load_cmd, dbname=self.db_name)
        self.logger.info(load_res)
        self.assertIn('CREATE EXTENSION', load_res, '执行失败' + text)

        text = '----step1:创建类型定义构造函数/menber/static方法;expect:成功----'
        self.logger.info(text)
        sql_cmd1 = f'''
        create or replace type {self.type} as object(
        id int,
        name text,
        constructor function {self.type}(self in out {self.type}, 
        id integer, name text) 
        return self as result,
        member function f1(a int) return int,
        member function f2( self in out {self.type}, b int) return int,
        member procedure p1( self in out {self.type}, b int),
        member procedure p2,
        static function s_f1() return int,
        static function s_f2(b int) return int ,
        static procedure s_p1 ,
        static procedure s_p2(name text));
        '''
        res1 = self.sh_primy.execut_db_sql(sql_cmd1, dbname=self.db_name)
        self.logger.info(res1)
        self.assertEqual('CREATE TYPE', res1, '执行失败' + text)

        text = '----step2:创建类型体;expect:成功----'
        self.logger.info(text)
        sql_cmd2 = f'''
            create or replace type body {self.type} as
            constructor function {self.type}( self in out {self.type}, 
            id integer , name text ) return self as result as
            begin
            self.id = id;
            self.name = name;
            end;
            member function f1(a int) return int as
            ret int := a;
            begin
            return ret;
            end;
            member function f2( self in out {self.type}, b int) return int
            as 
            begin
            raise info 'member function f2 self:%', self;
            return b;
            end;
            member procedure p1( self in out {self.type}, b int) as
            begin
            raise info 'member procedure p1 : name=>%', self.name;
            end;
            member procedure p2 as
            begin
            raise info 'member procedure p2 : name=>%', self.name;
            end;
            static function s_f1() return int as 
            begin
            raise info 'static function s_f1 ';
            return 1;
            end;
            static function s_f2(b int) return int as 
            begin
            raise info 'static function s_f2 ';
            return b;
            end;
            static procedure s_p1 as 
            begin
            raise info 'static function s_p1 ';
            end;
            static procedure s_p2(name text) as 
            begin
            raise info 'static function s_p2 name:%',name;
            end;
            end ;
            '''
        res2 = self.sh_primy.execut_db_sql(sql_cmd2, dbname=self.db_name)
        self.logger.info(res2)
        self.assertEqual('CREATE TYPE', res2, '执行失败' + text)

        text = '----step3:调用类型体member、static方法；expect:成功----'
        self.logger.info(text)
        sql_cmd3 = f'''
            declare
            var {self.type} := {self.type}(id=>1,name=>'23');
            result integer;
            begin
            result := var.f1(1);
            raise info '%',var;
            raise info 'member function f1:%',var.f1(1);
            raise info 'member function f1:%',var.f2(1);
            raise info 'member procedure p1:%', var.p1(1);
            var.name := 'vbase';
            raise info 'member procedure p2:%', var.p2();
            raise info 'static function s_f1:%',{self.type}.s_f1();
            raise info 'static function s_f2:%',{self.type}.s_f2(2);
            raise info 'static procedure s_p1:%',{self.type}.s_p1();
            raise info 'static procedure s_p2:%',{self.type}.s_p2('vbase');
            end;
            '''
        res3 = self.sh_primy.execut_db_sql(sql_cmd3, dbname=self.db_name)
        self.logger.info(res3)
        self.assertIn('ANONYMOUS BLOCK EXECUTE', res3, '执行失败' + text)

    def tearDown(self):
        text = '----step1:清理环境;expect:成功----'
        cle_cmd1 = f'drop type {self.type};'
        cle_res1 = self.sh_primy.execut_db_sql(cle_cmd1, dbname=self.db_name)
        self.logger.info(cle_res1)
        self.assertEqual('DROP TYPE', cle_res1, text + '执行失败')
        self.logger.info(f'---{os.path.basename(__file__)} end---')
